package org.sysdance.aplicativo.util;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Collection;
import java.util.LinkedList;

import org.apache.commons.lang.WordUtils;
import org.sysdance.aplicativo.enums.PermissaoUsuarioEnum;
import org.sysdance.aplicativo.enums.SexoEnum;
import org.sysdance.aplicativo.enums.TurnoEnum;

public class ResultSetUtil {
	
	private static final char UNDERLINE = '_';
	
	private ResultSetUtil() {
		super();
	}
	
	public static <T> T extrairUnicoRegistro(final ResultSet cursor, final Class<T> tipo){
		if(cursor != null && tipo != null){
			try{
				final ResultSetMetaData rsmd = cursor.getMetaData();
				if(cursor.next()){
						T objeto = tipo.newInstance();	
						loop:for(int i = 0; i < rsmd.getColumnCount();i++){
								final String str = WordUtils.capitalizeFully(rsmd.getColumnName(i + 1),new char[]{UNDERLINE});
								try{
									final Field atributo = objeto.getClass().getDeclaredField(converter(str));
									if(!atributo.isAccessible()){
										atributo.setAccessible(true);
									}
									if(atributo.getType().isEnum()){
										if(atributo.getType().equals(TurnoEnum.class)){
											atributo.set(objeto, TurnoEnum.getEnum(cursor.getInt(i + 1)));
										}else if(atributo.getType().equals(PermissaoUsuarioEnum.class)){
											atributo.set(objeto, PermissaoUsuarioEnum.getEnum(cursor.getInt(i + 1)));
										}else if(atributo.getType().equals(SexoEnum.class)){
											atributo.set(objeto, SexoEnum.getEnum(cursor.getInt(i + 1)));
										}else{
											atributo.set(objeto, null);
										}
									}else{
										atributo.set(objeto, cursor.getObject(i + 1));	
									}
								}catch(Exception e){
									continue loop;
								}
							}
						return objeto;
				}else{
					return null;
				}
			}catch(Exception e){
				SysDanceUtil.getInstancia().imprimirLog(e);
				return null;
			}
		}else{
			return null;
		}
	}
	
	public static <T> Collection<T> extrair(final ResultSet cursor, final Class<T> tipo){
		if(cursor != null && tipo != null){
			try{
				final Collection<T> resultado = new LinkedList<T>();
				final ResultSetMetaData rsmd = cursor.getMetaData();
				while(cursor.next()){
						T objeto = tipo.newInstance();	
						loop:for(int i = 0; i < rsmd.getColumnCount();i++){
								final String str = WordUtils.capitalizeFully(rsmd.getColumnName(i + 1),new char[]{UNDERLINE});
								try{
									final Field atributo = objeto.getClass().getDeclaredField(converter(str));
									if(!atributo.isAccessible()){
										atributo.setAccessible(true);
									}
									if(atributo.getType().isEnum()){
										if(atributo.getType().equals(TurnoEnum.class)){
											atributo.set(objeto, TurnoEnum.getEnum(cursor.getInt(i + 1)));
										}else if(atributo.getType().equals(PermissaoUsuarioEnum.class)){
											atributo.set(objeto, PermissaoUsuarioEnum.getEnum(cursor.getInt(i + 1)));
										}else if(atributo.getType().equals(SexoEnum.class)){
											atributo.set(objeto, SexoEnum.getEnum(cursor.getInt(i + 1)));
										}else{
											atributo.set(objeto, null);
										}
									}else{
										atributo.set(objeto, cursor.getObject(i + 1));	
									}
								}catch(Exception e){
									continue loop;
								}
							}
					  resultado.add(objeto);	
				}
				return resultado;
			}catch(Exception e){
				SysDanceUtil.getInstancia().imprimirLog(e);
				return new LinkedList<T>();
			}
		}else{
			return new LinkedList<T>();
		}
	}
	
	private static String converter(final String camelCase){
		final StringBuilder sb = new StringBuilder();
		sb.append(String.valueOf(camelCase.charAt(0)).toLowerCase());
		sb.append(camelCase.substring(1, camelCase.length()).replace(String.valueOf(UNDERLINE), ""));
		return sb.toString();
	}
}
